<script setup>
import * as Cesium from 'cesium'
import "./Widgets/widgets.css"
import { onMounted } from "vue";
import { ref } from "vue";
import planeData from "@/assets/json/plane.json"

//设置cesium的token
Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzYWQ3M2UyYy02MzRkLTQ5NTItOTg4NC1jNjZlZWE5MTc3OTQiLCJpZCI6MzI4NTkyLCJpYXQiOjE3NTQzMTY3NTF9.qgslX57Tbhb9TiQC8gzDrTdPaA0VnGVG7RVmcJJwrJ0"

//设置cesium静态资源的路径
window.CESIUM_BASE_URL = "/";
//因为前文把Cesium挂载到全局，所以这里直接用Cesium.Viewer()创建

//查看器编辑
onMounted(async () => {
  const viewer = new Cesium.Viewer('cesiumContainer', {
    // 去掉默认信息框的报错
    infoBox: false,
    // 自动播放
    shouldAnimate: true,
  });

  // 使用 await 正确处理异步加载
  viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
    requestWaterMask: true,
    requestVertexNormals: true
  });

  // 手动设置相机位置
  viewer.camera.flyTo({
    destination: Cesium.Rectangle.fromDegrees(
        89.55, 20.4,  // 西南角经纬度
        110.4, 61.5   // 东北角经纬度
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90)
    }
  });

  /*//地图叠加
  const imageryLayers = viewer.imageryLayers;
  const layer = imageryLayers.addImageryProvider(
      new Cesium.OpenStreetMapImageryProvider({
        url: "https://tile.openstreetmap.org",
      })
  );
  //设置图层透明度
  layer.alpha = 0.5;*/
  //隐藏logo
  viewer.cesiumWidget.creditContainer.style.display = "none";

  //setview相机到达指定位置，视角到达指定视角
  //例子生成目的地天安门的position
  // viewer.camera.setView({
  //   destination : Cesium.Cartesian3.fromDegrees(
  //       Cesium.Camera.DEFAULT_VIEW_RECTANGLE.west,
  //       Cesium.Camera.DEFAULT_VIEW_RECTANGLE.south,
  //       100000
  //   ),
  // })
//   const position = Cesium.Cartesian3.fromDegrees(116.397428,39.90923,100)
//   viewer.camera.setView({
//     //指定相机位置
//       destination : position,
//     //指定相机视角
//     orientation : {
//         //相机的朝向
//         heading: Cesium.Math.toRadians(0),
// //相机的俯仰角
//       pitch : Cesium.Math.toRadians(-90),
//       //相机的滚转角
//       roll  : 0,
//     },
//
//     })
  //飞到某个位置
  // viewer.camera.flyTo({
  //   destination : Cesium.Cartesian3.fromDegrees(110.4,20.4,100),
  //   orientation : {
  //     heading: Cesium.Math.toRadians(0),
  //     pitch : Cesium.Math.toRadians(-90),
  //     roll  : 0,
  //   }
  // })

  //通过虚拟按键进行相机移动
  document.addEventListener('keydown', function(e) {
    if (e.keyCode === 65)//A
      viewer.camera.moveLeft(viewer.camera.positionCartographic.height / 10);
      if (e.keyCode === 68)//D
        viewer.camera.moveRight(viewer.camera.positionCartographic.height / 10);
        if (e.keyCode === 87)//W
          viewer.camera.moveForward(viewer.camera.positionCartographic.height / 10);
        if (e.keyCode === 83)//S
          viewer.camera.moveBackward(viewer.camera.positionCartographic.height / 10);
    if (e.keyCode === 71) {
      // 实现相机向右滚转
      const heading = viewer.camera.heading;
      const pitch = viewer.camera.pitch;
      const roll = viewer.camera.roll + Cesium.Math.toRadians(5); // 增加5度滚转
      viewer.camera.setView({
        orientation: {
          heading: heading,
          pitch: pitch,
          roll: roll
        }
      });
    }
    if (e.keyCode === 72) {//H
      // 实现相机向左滚转
      const heading = viewer.camera.heading;
      const pitch = viewer.camera.pitch;
      const roll = viewer.camera.roll - Cesium.Math.toRadians(5); // 减少5度滚转
      viewer.camera.setView({
        orientation: {
          heading: heading,
          pitch: pitch,
          roll: roll
        }
      });
    }
    if (e.keyCode === 81) {
      viewer.camera.lookLeft( Cesium.Math.toRadians(0.15));
    }
    if (e.keyCode === 69) {
      viewer.camera.lookRight( Cesium.Math.toRadians(0.15));
    }
  });


  //生成天安门的位置为position1
  const position1 = Cesium.Cartesian3.fromDegrees(116.397428,39.90923,100)
  //生成中国石油大学克拉玛依校区的位置为position2
  const position2 = Cesium.Cartesian3.fromDegrees(84.91941400000004,45.545330000000005,500)
  const position3 = Cesium.Cartesian3.fromDegrees(84.91911400000004,45.543330000000005,500)


  //创建一个点,添加一个实体
  const point = viewer.entities.add({
    position: position1,
    point: {
      pixelSize: 10,
      color: Cesium.Color.RED,
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    }
  });
  //在position2位置创建一个点，图标为ic_1508.png
  const point2 = viewer.entities.add({
    position: position2,
    billboard: {
      image: '/texture/sky？/ic_1508.png',
      scale: 0.65,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    }
  })
  //在position2位置设置一个文字标签和广告牌
  const label = viewer.entities.add({
    position: position2,
    label: {
      text: '神秘人物出没点',
      font: '20px sans-serif',
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      outlineWidth: 2,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(0, 0)
    },
    billboard: {
      image: '/texture/sky？/ic_1614.png',
      scale: 0.65,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      //设置其显示位置
      pixelOffset: new Cesium.Cartesian2(-80, 0),
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER
    }
  })
  const point3 = viewer.entities.add({
    position: position3,
    billboard: {
      image: '/texture/sky？/ic_1616.png',
      scale: 0.65,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    }
  })

  //添加3d建筑
  const osmBuildings = viewer.scene.primitives.add(
      await Cesium.createOsmBuildingsAsync()
  );

  // primitive创建矩形
  const rectangle = viewer.entities.add({
    rectangle: {
      coordinates: Cesium.Rectangle.fromDegrees(
          90,20,110,30
      ),
      material: Cesium.Color.RED.withAlpha(0.5),
      height: 0,
      vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
      // outline: true,
      // outlineColor: Cesium.Color.BLACK,
      // outlineWidth: 2,
      // zIndex: 0
    }
  });
  //创建实例
  const instances = new Cesium.GeometryInstance({
    geometry: new Cesium.RectangleGeometry({
      rectangle: Cesium.Rectangle.fromDegrees(
          90,20,110,30
      ),
      vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
    }),
    modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position3),
    attributes: {
      color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.5))
    }
  })
  //设置外观
  const appearance = new Cesium.PerInstanceColorAppearance({
    flat: true,
    translucent: false,
  })
  const material = new Cesium.Material({
    fabric: {
      type: 'Color',
      uniforms: {
        color: Cesium.Color.RED.withAlpha(0.5)
      }
    }
  })
  //创建图元
  const primitive = viewer.scene.primitives.add(
      new Cesium.Primitive({
        geometryInstances: instances,
        appearance: new Cesium.PerInstanceColorAppearance({
          flat: true,
          translucent: false
        })
      })
  )//这段代码会直接构建一个上面的矩形因为前文都规定好了,与下面的一小段作用相同
  // const primitive = new Cesium.Primitive({
  //   geometryInstances: instances,
  //   appearance: appearance
  // });
  // viewer.scene.primitives.add(primitive);

  //拾取
  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.setInputAction(function(movement) {
    console.log(movement.position);
    const pick = viewer.scene.pick(movement.position);
    console.log(pick);
    if (Cesium.defined(pick)) {
      console.log(pick.id);
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);


  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewer.scene.globe.show = true;

  //添加3D模型，到position3位置
  const airplane = viewer.entities.add({
    // position: position3,
    orientation: Cesium.Transforms.headingPitchRollQuaternion(
        position3,
        new Cesium.HeadingPitchRoll(0, 0, 0)
    ),
    model: {
      uri: '/model/CesiumAir/Cesium_Air.glb',
      scale: 2.0,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND

    }
  })

  //GEO数据加载
  // const geojson = await Cesium.GeoJsonDataSource.load('/geojson/geojson.json',
  // {
  //   stroke: Cesium.Color.RED,
  //   fill: Cesium.Color.YELLOW,
  //   strokeWidth: 5,
  // }
  // );
  // viewer.dataSources.add(geojson);
//（也可以直接用dataSources.add(Cesium.GeoJsonDataSource.load('/geojson/geojson.json'))进行加载
// ）

  //kml数据的加载
  // const kml = await Cesium.KmlDataSource.load('/kml/kml.kml');（也可以使用url进行访问）
  //console.log(kml);
  //viewer.dataSources.add(kml);

  console.log(planeData);
  const positionProperty = Cesium.SampledPositionProperty.fromCartesianArray(
      planeData.positions,
      planeData.epoch,
      Cesium.Cartesian3
  );
  //创建时间间隔
  // const timeInterval = Cesium.JulianDate.secondsDifference(
  //     Cesium.JulianDate.addSeconds(planeData.epoch, 0, new Cesium.JulianDate()),
  //     Cesium.JulianDate.addSeconds(planeData.epoch, timeInterval, new Cesium.JulianDate())
  // )//此时为json中已经含有时间间隔
  const timeInterval = 30;
  //整个飞行的时间
  const duration = (planeData.positions.length - 1) * timeInterval;
  //设置起点时间
  const Time = new Date("2025-08-17T00:50:12Z");
  const startTime = Cesium.JulianDate.fromDate(Time);
  const endTime = Cesium.JulianDate.addSeconds(startTime, duration, new Cesium.JulianDate());


  //将查看器的时间调整到起点与结束点的范围
  viewer.clock.startTime = startTime.clone();
  viewer.clock.stopTime = endTime.clone();
  viewer.clock.currentTime = startTime.clone();

  viewer.timeline.zoomTo(startTime, endTime);

  planeData.forEach((dataPoint , i)=> {
     const time = Cesium.JulianDate.addSeconds(startTime, i * timeInterval, new Cesium.JulianDate());
    // 设置飞机的位置
    const position = Cesium.Cartesian3.fromDegrees(
        dataPoint.longitude,
        dataPoint.latitude,
        dataPoint.height
    );
    positionProperty.addSample(time, position);
    //显示一下点
    viewer.entities.add({
      position: position,
      point: {
        pixelSize: 5,
        color: Cesium.Color.RED,
        outline: true,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2
      }
    })
  })

  //加载一个飞机
  const plane = viewer.entities.add({
    id: 'Plane',
    //在时间内可用
    availability: new Cesium.TimeIntervalCollection([
        new Cesium.TimeInterval(
            {
                start:startTime,
                stop: endTime,
            }
        )
    ]),
    position: positionProperty,
    model: {
      uri: '/model/CesiumAir/Cesium_Air.glb',
      scale: 2.0,
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
    } ,
    orientation: new Cesium.VelocityOrientationProperty(positionProperty),
    //绘制轨迹线
    path: new Cesium.PathGraphics({
      material: Cesium.Color.RED.withAlpha(0.5),
      width: 5
    })
  })

  //相机追踪运动的物体
  viewer.trackedEntity = plane;

  //弧度与角度的转换
  const radians = Cesium.Math.toRadians(110.4);
  console.log(radians);
  const degrees = Cesium.Math.toDegrees(radians);
  console.log(degrees);

  //经纬度转换为笛卡尔坐标
  const cartesian3 = Cesium.Cartesian3.fromDegrees(110.4, 20.4, 0);
  //后续上文的坐标可以使用鼠标事件进行填入
  console.log(cartesian3);
  //笛卡尔坐标转换为经纬度
  const cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
  console.log(cartographic);


});
</script>

<template>

  <div id="cesiumContainer" ref="cesiumContainer">

  </div>
</template>

<style scoped>

* {
  margin: 0;
  padding: 0;
}
#cesiumContainer {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
}
</style>
